package com.wanho.java156.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wanho.es.repositories.ProdcutRepository;
import com.wanho.java156.mapper.ProductMapper;
import com.wanho.java156.po.Product;
import com.wanho.java156.po.ProductExample;
import com.wanho.java156.util.IDUtil;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class ProductService {
    @Autowired
    private ProductMapper productMapper ;
    @Autowired
    private ProdcutRepository prodcutRepository ;
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate ;
    @Autowired
    private IDUtil idUtil ;

    /**
     * 根据产品id 进行ES 检索产品信息
     * @param productId
     * @return
     */
    public Product searchById(String productId){
        Optional<Product> optional = prodcutRepository.findById(productId);
        if (optional.isPresent()){
            return  optional.get() ;
        }
        return  null ;
    }

    /**
     * 使用ES实现搜索： query_String 分词器  高亮显示
     * @param pageNum
     * @param keyword
     * @return
     */
    public Page<Product> search(int pageNum,String keyword){
        Pageable pageable = PageRequest.of(pageNum - 1, 8) ;
        //没有输入关键字
        if (StringUtils.isEmpty(keyword)){
            //查询前 8 条数据
            return prodcutRepository.findAll(pageable) ;
        }
        //创建一个查询对象
        NativeSearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.queryStringQuery(keyword).defaultField("productname"))
                .withHighlightFields(new HighlightBuilder.Field("productname").preTags("<font color='red'>").postTags("</font>"))
                .withPageable(pageable)
                .build();
        //执行查询
        Page<Product> productPage = elasticsearchTemplate.queryForPage(query, Product.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse searchResponse, Class<T> aClass, Pageable pageable) {
                List<Product> imageTemp = new ArrayList<>();
                SearchHits hits = searchResponse.getHits();
                try {
                    for (SearchHit searchHit : hits) {
                        Map<String, Object> documentMap = searchHit.getSource();
                        Product product = new Product();
                        BeanUtils.populate(product, documentMap);
                        Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                        //取title高亮显示的结果
                        HighlightField field = highlightFields.get("productname");
                        Text[] fragments = field.getFragments();
                        if (fragments != null) {
                            String productname = fragments[0].toString();
                            BeanUtils.setProperty(product, "productname", productname);
                        }
                        imageTemp.add(product) ;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return new AggregatedPageImpl<>((List<T>) imageTemp);
            }
        });
        return productPage ;
    }

    /**
     * ES 索引库查询
     * @param pageNum
     * @param keyword
     * @return
     */
    /*public Page<Product> search(int pageNum, String keyword){
        Pageable pageable = PageRequest.of(pageNum - 1, 8) ;
        Page page ;
        //如果关键词为空 从 ES 库中 查询所有产品
        if (StringUtils.isEmpty(keyword)){
            page = prodcutRepository.findAll(pageable) ;
        }else{
            page = prodcutRepository.findProductsByProductnameOrProductdesc(keyword, keyword, pageable);
        }
       return page ;
    }*/

    /**
     * 分页 + 条件查询
     * @param pageNum 页码 第几页？
     * @param pageSize 分页跨度  每页显示多少行？
     * @param productname  模糊查询的产品名称
     * @return
     */
    public PageInfo<Product> list(int pageNum, int pageSize, String productname){
        //获取第1页，10条内容，默认查询总数count
        PageHelper.startPage(pageNum, pageSize);
        ProductExample productExample = new ProductExample();
        //判断是否带模糊条件查询
        if (StringUtils.isNotEmpty(productname)){
            productExample.createCriteria().andProductnameLike("%"+productname+"%") ;
        }
        List<Product> orderList = productMapper.selectByExample(productExample);
        return new PageInfo<>(orderList) ;
    }

    public boolean save(Product product) {
        product.setId(idUtil.randId());
        return productMapper.insert(product)>0;
    }

    public Product findById(String id) {
        return productMapper.selectByPrimaryKey(id) ;
    }

    public boolean modify(Product product) {
        return productMapper.updateByPrimaryKey(product) >0;
    }

    public List<Product> selectAll() {
        return productMapper.selectByExample(new ProductExample()) ;
    }
}
